package com.cms.work.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.cms.work.entity.enums.CommonEnum.ResourceTypeEnum;
import com.cms.work.entity.enums.CommonEnum.UserStatusEnum;
import com.cms.work.entity.sys.ActiveUser;
import com.cms.work.entity.sys.Menus;
import com.cms.work.entity.sys.Permissions;
import com.cms.work.entity.sys.SysUser;
import com.cms.work.entity.sys.vo.SysRoleResourceVo;
import com.cms.work.service.sys.ISysResourceService;
import com.cms.work.service.sys.ISysUserService;

public class CmsAuthorizingRealm extends AuthorizingRealm {
	
	private static final Logger logger = LoggerFactory.getLogger(CmsAuthorizingRealm.class);
    
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysResourceService sysResourceService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        try {
            logger.info("=====用户权限验证=====");
            ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
            
            List<Permissions> permissionList = activeUser.getPermissionList();
            if(permissionList != null && permissionList.size() > 0){
            	for (Permissions permission : permissionList) {
            		authorizationInfo.addStringPermission(permission.getUrl());
				}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return authorizationInfo;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        SimpleAuthenticationInfo authenticationInfo = null;
        logger.info("=====用户开始认证=====");
        ActiveUser activeUser = new ActiveUser();
        
        String usercode = (String) token.getPrincipal();
        List<SysUser> userDB = sysUserService.selectByCondition(new SysUser(usercode));
        if(userDB == null || userDB.size()==0) {
            throw new UnknownAccountException();
        }
        
        if(userDB.get(0).getStatus() == UserStatusEnum.disable.status){
        	throw new DisabledAccountException();
        }
        //用户信息
        SysUser user = userDB.get(0);
        activeUser.setUserId(user.getId());
        activeUser.setLoginCode(user.getLoginCode());
        activeUser.setUserName(user.getUserName());
        //用户资源权限
        List<SysRoleResourceVo> resourceList = sysResourceService.getResourceByUserId(user.getId());
        List<Permissions> permissionList = null;
    	List<Menus> menuList = null;
        if(resourceList != null && resourceList.size() > 0){
        	permissionList = new ArrayList<Permissions>();
        	menuList = new ArrayList<Menus>();
        	for (SysRoleResourceVo resourceVo : resourceList) {
        		String url = resourceVo.getUrl();
        		if(resourceVo.getType() == ResourceTypeEnum.menu.getType()){
        			Menus menu = new Menus();
        			menu.setId(resourceVo.getId());
        			menu.setpId(resourceVo.getPid());
        			menu.setCode(resourceVo.getCode());
        			menu.setName(resourceVo.getName());
        			menu.setIcon(resourceVo.getIcon());
        			menu.setUrl(url);
        			menuList.add(menu);
        		}else{
        			if(StringUtils.isNotBlank(url)){
        				Permissions permission = new Permissions();
        				permission.setName(resourceVo.getName());
        				permission.setUrl(url);
        				permissionList.add(permission);
        			}
        		}
			}
        	activeUser.setMenuList(menuList);
        	activeUser.setPermissionList(permissionList);
        }
        
        authenticationInfo = new SimpleAuthenticationInfo(activeUser, user.getPassword(), this.getName());
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("userId", activeUser.getUserId());
        session.setAttribute("menuList", menuList);
        session.setAttribute("activeUser", activeUser);
        return authenticationInfo;
    }

}
